package com.company.cloud.coupon.modules.app.service.impl;

import java.time.LocalDateTime;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.company.cloud.common.asserts.ValidatorUtils;
import com.company.cloud.common.bean.LoginSimpleUserInfo;
import com.company.cloud.common.bean.LoginUserInfo;
import com.company.cloud.common.constant.BaseConstant.EnabledEnum;
import com.company.cloud.common.constant.BaseReturnEnum;
import com.company.cloud.common.exception.BusinessException;
import com.company.cloud.common.utils.CheckUtils;
import com.company.cloud.common.utils.LocalDateTimeUtils;
import com.company.cloud.coupon.constant.CouponConstant.CouponActStateEnum;
import com.company.cloud.coupon.constant.CouponConstant.CouponGetType;
import com.company.cloud.coupon.constant.CouponConstant.CouponObjType;
import com.company.cloud.coupon.constant.CouponErrorEnum;
import com.company.cloud.coupon.modules.app.controller.req.CouponFissionDrawByActParam;
import com.company.cloud.coupon.modules.app.controller.req.CouponFissionDrawByShareParam;
import com.company.cloud.coupon.modules.app.controller.req.CouponFissionShareParam;
import com.company.cloud.coupon.modules.app.service.CouponFissionService;
import com.company.cloud.coupon.modules.app.service.CouponService;
import com.company.cloud.coupon.modules.base.entity.CouponFissionActInfo;
import com.company.cloud.coupon.modules.base.entity.CouponFissionInfo;
import com.company.cloud.coupon.modules.base.entity.CouponInfo;
import com.company.cloud.coupon.modules.base.service.CouponFissionActInfoService;
import com.company.cloud.coupon.modules.base.service.CouponFissionInfoService;
import com.company.cloud.coupon.modules.base.service.CouponInfoService;
import com.company.cloud.coupon.modules.cache.models.CouponFissionModel;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;

@Service
public class CouponFissionServiceImpl implements CouponFissionService{

	
	@Autowired
	private CouponFissionInfoService couponFissionInfoService;
	@Autowired
	private CouponFissionActInfoService couponFissionActInfoService;
	@Autowired
	private CouponInfoService couponInfoService;
	@Autowired
	private CouponService couponService;
	
	
	
	@Override
	public CouponFissionModel drawCouponFissionByAct(CouponFissionDrawByActParam param, LoginSimpleUserInfo userInfo) {
		ValidatorUtils.validate(param);
		CouponFissionActInfo entity=couponFissionActInfoService.getById(param.getId());
		if(entity==null || EnabledEnum.DISABLED.getCode().equals(entity.getRowsState())) {
			throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
		}
		if(!CouponActStateEnum.CFS_ING.getCode().equals(entity.getState())) {
			throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
		}
		if(LocalDateTimeUtils.compare(entity.getStarDate(), LocalDateTime.now())>0) {
			throw new BusinessException(CouponErrorEnum.CouponFission_Verdue);
		}
		if(LocalDateTimeUtils.compare(entity.getEndDate(), LocalDateTime.now())<0) {
			throw new BusinessException(CouponErrorEnum.CouponFission_Verdue);
		}
		
		CouponFissionInfo couponFission=new CouponFissionInfo();
		couponFission.setCompanyNo(entity.getCompanyNo());
		couponFission.setCouponFissionActId(entity.getId());
		couponFission.setStarDate(entity.getStarDate());
		couponFission.setEndDate(entity.getEndDate());
		couponFission.setHaveDate(LocalDateTime.now());
		couponFission.setHaveUserId(userInfo.getId());
		couponFission.setHaveIp(userInfo.getIp());
		couponFission.addCreateParam(userInfo);
		couponFission.addEditParam(userInfo);
		couponFissionInfoService.save(couponFission);
		return null;
	}
	
	

	@Override
	public void drawCouponByShare(CouponFissionDrawByShareParam param, LoginSimpleUserInfo userInfo) {
		ValidatorUtils.validate(param);
		CouponFissionInfo entity=couponFissionInfoService.getById(param.getId());
		if(entity==null) {
			throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
		}
		
		CouponFissionActInfo cfaInfo=couponFissionActInfoService.getById(entity.getCouponFissionActId());
		if(cfaInfo==null) {
			throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
		}
		
		if(LocalDateTimeUtils.compare(entity.getStarDate(), LocalDateTime.now())>0) {
			throw new BusinessException(CouponErrorEnum.CouponFission_Verdue);
		}
		
		if(LocalDateTimeUtils.compare(entity.getEndDate(), LocalDateTime.now())<0) {
			throw new BusinessException(CouponErrorEnum.CouponFission_Verdue);
		}
		
		//领取总数判断
		int num=couponInfoService.count(new QueryWrapper<CouponInfo>()
				.eq("source_biz_type", CouponObjType.CouponFission_ObjType)
				.eq("source_biz_id", entity.getId())
				);
		if(num>=cfaInfo.getCouponGiveNum()) {
			throw new BusinessException(CouponErrorEnum.CouponFission_GiveEnd);
		}
		
		if(CouponGetType.CFG_Day_Num.getCode().equals(cfaInfo.getMemberGetNumType())) {
			//每人每天最多领取?次
			int dayNum= couponInfoService.count(new QueryWrapper<CouponInfo>()
					.eq("have_user_id", userInfo.getId())
					.eq("source_biz_type", CouponObjType.CouponFission_ObjType)
					.inSql("source_biz_id",StrUtil.format(
							"select id from op_coupon_fission_info where coupon_fission_act_id={}", 
							entity.getCouponFissionActId()))
					.eq("date_format(have_date ,'%Y-%m-%d' )", DateUtil.today())
					);
			if(dayNum>=cfaInfo.getMemberGetNum().intValue()) {
				throw new BusinessException(CouponErrorEnum.CouponFission_GiveNum);
			}
		}else if(CouponGetType.CFG_Act_Num.getCode().equals(cfaInfo.getMemberGetNumType())) { 
			//每人活动期间最多领取?次
			int actNum= couponInfoService.count(new QueryWrapper<CouponInfo>()
					.eq("have_user_id", userInfo.getId())
					.eq("source_biz_type", CouponObjType.CouponFission_ObjType)
					.inSql("source_biz_id",StrUtil.format(
							"select id from op_coupon_fission_info where coupon_fission_act_id={}", 
							entity.getCouponFissionActId()))
					);
			if(actNum>=cfaInfo.getMemberGetNum().intValue()) {
				throw new BusinessException(CouponErrorEnum.CouponFission_GiveNum);
			}
		}
		//随机优惠券是否最佳手气判断
		boolean isMaxFlag=false;
		if(CheckUtils.hasInt(cfaInfo.getMaxIndex())) {
			if((num+1)==cfaInfo.getMaxIndex().intValue()) {
				isMaxFlag=true;
			}
		}
		
		couponService.collectCoupon(userInfo.getId(), cfaInfo.getCouponConfigId(),
				CouponObjType.CouponFission_ObjType, entity.getId(), isMaxFlag, userInfo);
		
		
		
	}



	@Override
	public void share(CouponFissionShareParam param, LoginSimpleUserInfo userInfo) {
		ValidatorUtils.validate(param);
		CouponFissionInfo entity=couponFissionInfoService.getById(param.getId());
		if(entity==null) {
			throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
		}
		entity.setShareUserId(userInfo.getId());
		entity.setShareDate(LocalDateTime.now());
		entity.setShareChannel(param.getShareChannel());
		entity.addEditParam(userInfo);
		couponFissionInfoService.updateById(entity);
	}
	
}
